package com.xxxx.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxxx.server.mapper.AdminMapper;
import com.xxxx.server.mapper.AdminRoleMapper;
import com.xxxx.server.mapper.RoleMapper;
import com.xxxx.server.pojo.Admin;
import com.xxxx.server.pojo.ReceiveChangePwdParams;
import com.xxxx.server.rest.RespBean;
import com.xxxx.server.pojo.Role;
import com.xxxx.server.service.IAdminService;
import com.xxxx.server.utils.AssertUtil;
import com.xxxx.server.utils.JwtUtils;
import com.xxxx.server.utils.PhoneUtil;
import com.xxxx.server.utils.PwdUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhoubin
 * @since 2020-10-15
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements IAdminService {

	@Autowired
	private UserDetailsService userDetailsService;
	@Autowired
	private PasswordEncoder passwordEncoder;
	@Autowired
	private BCryptPasswordEncoder pwdEncoder;
	@Autowired
	private JwtUtils jwtUtils;
	@Value("${jwt.tokenHead}")
	private String tokenHead;
	@Resource
	private AdminMapper adminMapper;
	@Resource
	private RoleMapper roleMapper;
	@Resource
	private AdminRoleMapper adminRoleMapper;



	/**
	 * 登录
	 * @param username
	 * @param password
	 * @return
	 */
	@Override
	public  RespBean login(String username, String password, String code, HttpServletRequest request) {
		String captcha = (String) request.getSession().getAttribute("captcha");
		if (StringUtils.isBlank(code)||!captcha.equals(code)){
			return RespBean.error("验证码错误!");
		}
		//从自定义登录逻辑中读取用户
		UserDetails userDetails = userDetailsService.loadUserByUsername(username);
		//判断用户是否存在
		if (null==userDetails||!passwordEncoder.matches(password,userDetails.getPassword())){
			throw new UsernameNotFoundException("用户名或密码不正确");
		}
		//判断用户是否启用
		if (!userDetails.isEnabled()){
			return RespBean.error("用户尚未启用，请联系管理员");
		}
		//将当前用户对象存入SpringSecurity全局上下文，方便其他方法使用
		// 获取  用户+凭证+权限
		UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails,
				null, userDetails.getAuthorities());
		//设置SpringSecurity全局上下文
		SecurityContextHolder.getContext().setAuthentication(authenticationToken);
		//生成token并返回
		String token = jwtUtils.generatorToken(userDetails);
		Map<String,Object> tokenMap = new HashMap<>();
		tokenMap.put("tokenHead",tokenHead);
		tokenMap.put("token",token);
		return RespBean.success("登录成功",tokenMap);
	}

	/**
	 * 根据用户名获取用户信息
	 * @param username
	 * @return
	 */
	@Override
	public Admin getUserByUsername(String username) {
		//根据用户名查询操作员信息
		return adminMapper.selectOne(new QueryWrapper<Admin>().eq("username", username));

	}

	@Override
	public List<Admin> selectAdminList(String s) {
		return adminMapper.selectList(null);
	}

	@Override
	public List<Role> getRoles(Integer id) {
		return roleMapper.getRolesByAdminId(id);
	}

	@Override
	public RespBean updateMyPic(Integer id, String userFace) {
		adminMapper.updateMyPic(id,userFace);
		return RespBean.success("修改头像成功！");
	}

	/**
	 * 修改admin信息实现:——
	 *   1.非空校验即不能全空
	 *   2.直接调用adminMapper
	 * @param admin
	 * @return
	 */
	@Override
	public RespBean updateAdminInfo(Admin admin) {
		//1.非空校验即不能空
		AssertUtil.isTrue(StringUtils.isBlank(admin.getName())
				||StringUtils.isBlank(admin.getPhone())
				||StringUtils.isBlank(admin.getTelephone())
				||StringUtils.isBlank(admin.getAddress()),"必填项不能为空！");
		//手机号码合法性判断
		AssertUtil.isTrue(!PhoneUtil.isPhone(admin.getPhone()),"手机号码不合法!");
		//2.直接调用adminMapper
		AssertUtil.isTrue(adminMapper.updateAdminInfo(admin)!=1,"修改失败!");
		//返回respBean
		return RespBean.success("修改成功！");
	}


	/**
	 * 修改密码实现：
	 *  1.3个密码非空校验
	 *  2.old正确
	 *  3.
	 *   3.1新密码不能与旧密码一致
	 *   3.2新密码的规范符合要求!
	 *  4.again密码与new一样
	 *  5.调用mapper，并判断成功与否
	 * @param
	 * @param
	 * @param
	 * @param
	 * @return
	 */
	@Override
	public RespBean changePwd(ReceiveChangePwdParams params) {
		//1.3个密码非空校验
		AssertUtil.isTrue(StringUtils.isBlank(params.getOldPass())
				||StringUtils.isBlank(params.getPass())
				||StringUtils.isBlank(params.getCheckPass()),"必填项不能为空!");
		//2.old正确
		//根据adminId查询用户对象
		Admin admin = adminMapper.selectById(params.getAdminId());
		AssertUtil.isTrue(!passwordEncoder.matches(params.getOldPass(),admin.getPassword()),"密码错误！");
		//  3.1新密码不能与旧密码一致;
		AssertUtil.isTrue(params.getPass().equals(params.getOldPass()),"新旧密码不能一致！");
		//  3.2新密码的规范符合要求!
		AssertUtil.isTrue(!PwdUtil.isValidPwd(params.getPass()),"密码设置不合法!");
		//4.again密码与new一样
		AssertUtil.isTrue(!params.getPass().equals(params.getCheckPass()),"两次密码要求一致!");
		//5.调用mapper，并判断成功与否！
		Integer id = admin.getId();
		AssertUtil.isTrue(adminMapper.changePwd(id,pwdEncoder.encode(params.getPass()))!=1,"修改失败!");
		//修改成功,返回respBean
		return RespBean.success("修改成功!");
	}


	//操作员信息查询
	@Override
	public List<Admin> selectAdminInfo(String keywords) {

		List<Admin> admins = adminMapper.selectAdminInfo(keywords);

		//如果admin为空。。。抛出异常
		//若admin不为空，查询改admin下所有角色集合
		//遍历查询到的admin集合。
		admins.forEach(t -> {
			//查询改admin下所有角色集合
			List<Role> roles = adminMapper.selectAdminRoleByAdminId(t.getId());
			//设置角色信息
			t.setRoles(roles);
		});

		return admins;
	}

	//查询操作员的角色信息
	@Override
	public List<Role> selectAdminRoleInfo() {
		return adminMapper.selectAdminRoleInfo();
	}

	@Override
	public Integer enableChange(Map<String, Object> admin) {
		return null;
	}


	//修改操作员的状态(启用和禁用)

	@Override
	public RespBean updateEnabledById(Map<String, Object> admin) {

		//管理员自己不能启用和禁用自己
		Integer adminId= (Integer) admin.get("id");
		if(adminId==1){
			return RespBean.error("管理员自己不能操作自己");
		}

		Boolean id = adminMapper.selectEnabledById((Integer) admin.get("id"));
		//adminMapper.selectEnabledById( (admin.get("id"));
		if (id) {
			Integer enabled = 0;
			int id1 = adminMapper.updateEnableById(enabled, (Integer) admin.get("id"));
			if (id1 > 0) {
				return RespBean.success("修改成功");
			} else return RespBean.error("修改失败");
		} else {

			Integer enabled = 1;
			int id1 = adminMapper.updateEnableById(enabled, (Integer) admin.get("id"));
			if (id1 > 0) {
				return RespBean.success("修改成功");
			} else return RespBean.error("修改失败");


		}
	}

	//删除管理员
	@Override
	public RespBean deleteAdminById(Integer id) {

		//执行删除操作
		List<Integer> adminIds=adminMapper.getAdminId(id);
		for (Integer adminId:adminIds){
			if (adminId==1){
				return RespBean.error("系统管理员不能自己删除自己");
			}
		}

		int i = adminMapper.deleteAdminById(id);

		if (i > 1) {
			return RespBean.error("删除失败");
		}
		return RespBean.success("删除成功");
	}


	@Override
	public RespBean updateRolesById(Integer adminId, Integer[] rids) {
		if (adminId== 1) {
			return RespBean.error("无法修改系统管理员账户的角色");
		}
		//删除当前操作员的所有角色
		adminRoleMapper.deleteAllrolesByAdminId(adminId);
		//循环为当前用户添加角色

		if (rids.length < 1) {
			return RespBean.success("修改成功");
		} else {

			//用作判断
			int sum = 0;
			//循环添加
			for (Integer rid : rids
			) {
				int i = adminRoleMapper.AddRoleByAdminId(adminId, rid);
				sum = sum + i;
			}
			//判断
			if (sum == rids.length) {
				return RespBean.success("角色更改成功");
			} else {
				return RespBean.error("角色更改失败");
			}

		}
	}
}






